import { NextRequest, NextResponse } from "next/server"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { generateJitsiToken, isJitsiJWTConfigured } from "@/lib/jitsi-jwt"; import { config } from "@/lib/config"; // GET /api/appointments/[id]/jitsi-token - Generar JWT token para Jitsi export async function GET( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params; const session = await getServerSession(authOptions); if (!session?.user?.id) { return NextResponse.json({ error: "No autorizado" }, { status: 401 }); } // Verificar si JWT está configurado if (!isJitsiJWTConfigured()) { return NextResponse.json( { error: "Jitsi JWT no está configurado", useJWT: false, domain: config.jitsi.domain, }, { status: 200 } ); } const user = await prisma.user.findUnique({ where: { id: session.user.id }, }); if (!user) { return NextResponse.json( { error: "Usuario no encontrado" }, { status: 404 } ); } const appointment = await prisma.appointment.findUnique({ where: { id }, include: { paciente: true, medico: true, }, }); if (!appointment) { return NextResponse.json( { error: "Cita no encontrada" }, { status: 404 } ); } // Validar que el usuario sea parte de la cita const isPatient = appointment.pacienteId === user.id; const isDoctor = appointment.medicoId === user.id; if (!isPatient && !isDoctor) { return NextResponse.json( { error: "No tienes acceso a esta cita" }, { status: 403 } ); } // Validar que la cita esté aprobada o completada if ( appointment.estado !== "APROBADA" && appointment.estado !== "COMPLETADA" ) { return NextResponse.json( { error: "Solo se pueden acceder a citas aprobadas" }, { status: 400 } ); } // Validar que tenga fecha asignada if (!appointment.fechaSolicitada) { return NextResponse.json( { error: "La cita no tiene fecha asignada" }, { status: 400 } ); } // Validar el tiempo: permitir unirse 15 minutos antes hasta 1 hora después const now = new Date(); const appointmentTime = new Date(appointment.fechaSolicitada); const fifteenMinutesBefore = new Date( appointmentTime.getTime() - 15 * 60 * 1000 ); const oneHourAfter = new Date( appointmentTime.getTime() + 60 * 60 * 1000 ); if (now < fifteenMinutesBefore) { const minutesUntil = Math.floor( (appointmentTime.getTime() - now.getTime()) / (60 * 1000) ); return NextResponse.json( { error: "Aún no es tiempo de la cita", message: `La cita será en ${minutesUntil} minutos. Podrás unirte 15 minutos antes.`, minutesUntil, }, { status: 400 } ); } if (now > oneHourAfter) { return NextResponse.json( { error: "La cita ya finalizó" }, { status: 400 } ); } // Determinar nombre de sala const roomName = appointment.roomName || `appointment-${id}`; // Si no existe roomName, crearlo if (!appointment.roomName) { await prisma.appointment.update({ where: { id }, data: { roomName }, }); } // Generar JWT token const userName = `${user.name} ${user.lastname || ""}`.trim(); const isModerator = user.role === "DOCTOR" || user.role === "ADMIN"; const avatarUrl = user.profileImage || undefined; const token = generateJitsiToken( user.id, userName, user.email || undefined, roomName, isModerator, avatarUrl, 7200 // 2 horas de expiración ); return NextResponse.json({ token, roomName, domain: config.jitsi.domain, userName, isModerator, useJWT: true, }); } catch (error) { console.error("Error al generar JWT token de Jitsi:", error); return NextResponse.json( { error: "Error al generar token de autenticación" }, { status: 500 } ); } }